import json
import re

from django import http
from django.core.cache import cache
from django.shortcuts import render
from django.views import View

from apps.areas.models import Areas, Address
from utils import contents
from utils.response_code import RETCODE


class AreasView(View):
    def get(self, request):

        area_id = request.GET.get('area_id')

        if not area_id:
            province_list = cache.get('province_list')
            if not province_list:

                try:
                    province_model_list = Areas.objects.filter(parent__isnull=True)

                    province_list = []

                    for province_model in province_model_list:
                        province_list.append({'id': province_model.id, 'name': province_model.name})

                    cache.set('province_list', province_list, 3600)
                except Exception as e:
                    return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '省份数据错误'})

            return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'province_list': province_list})

        else:
            sub_data = cache.get('sub_area_' + area_id)
            if not sub_data:
                try:
                    parent_model = Areas.objects.get(id=area_id)
                    sub_model_list = parent_model.subs.all()

                    sub_list = []
                    for sub_model in sub_model_list:
                        sub_list.append({'id': sub_model.id, 'name': sub_model.name})

                    sub_data = {
                        'id': parent_model.id,
                        'name': parent_model.name,
                        'subs': sub_list
                    }
                    cache.set('sub_area_' + area_id, sub_data, 3600)
                except Exception as e:
                    return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '城市或区数据错误'})

            return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'sub_data': sub_data})


class CreateAddressView(View):
    def post(self, request):
        count = request.user.addresses.count()

        if count >= contents.USER_ADDRESS_COUNTS_LIMIT:
            return http.JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '地址超出上限'})

        json_dict = json.loads(request.body.decode())
        city_id = json_dict.get('city_id')
        district_id = json_dict.get('district_id')
        email = json_dict.get('email')
        mobile = json_dict.get('mobile')
        place = json_dict.get('place')
        province_id = json_dict.get('province_id')
        receiver = json_dict.get('receiver')
        tel = json_dict.get('tel')

        if not all([city_id, district_id, mobile, place, province_id, receiver]):
            return http.HttpResponseBadRequest('缺少必传参数')

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('手机号不正确')

        if tel:
            if not re.match(r'(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return http.HttpResponseBadRequest('参数tel有误')

        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return http.HttpResponseBadRequest('参数email有误')

        try:
            address = Address.objects.create(user=request.user,
                                             title=receiver,
                                             city_id=city_id,
                                             district_id=district_id,
                                             email=email,
                                             mobile=mobile,
                                             place=place,
                                             province_id=province_id,
                                             receiver=receiver,
                                             tel=tel)

            if not request.user.default_address:
                request.user.default_address = address
                request.user.save()
        except Exception as e:
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '新增地址失败'})

        address_dict = {
            'id': address.id,
            'city': address.city.name,
            'district': address.district.name,
            'email': address.email,
            'mobile': address.mobile,
            'place': address.place,
            'province': address.province.name,
            'receiver': address.receiver,
            'tel': address.tel,
            'title': address.title
        }

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '新增地址成功', 'address': address_dict})


class UpdateAreasView(View):
    def put(self, request, address_id):
        address = Address.objects.get(id=address_id)
        if not (address and address.user == request.user):
            return http.HttpResponseBadRequest('非法操作')

        json_dict = json.loads(request.body.decode())
        city_id = json_dict.get('city_id')
        district_id = json_dict.get('district_id')
        email = json_dict.get('email')
        mobile = json_dict.get('mobile')
        place = json_dict.get('place')
        province_id = json_dict.get('province_id')
        receiver = json_dict.get('receiver')
        tel = json_dict.get('tel')

        if not all([city_id, district_id, mobile, place, province_id, receiver]):
            return http.HttpResponseBadRequest('缺少必传参数')

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('参数mobile不正确')

        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return http.HttpResponseBadRequest('参数tel有误')

        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return http.HttpResponseBadRequest('参数email有误')

        try:
            Address.objects.filter(id=address_id).update(
                user=request.user,
                title=receiver,
                city_id=city_id,
                district_id=district_id,
                email=email,
                mobile=mobile,
                place=place,
                province_id=province_id,
                receiver=receiver,
                tel=tel
            )
        except Exception as e:
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '更新地址失败'})

        address = Address.objects.get(id=address_id)
        address_dict = {
            'id': address.id,
            'city': address.city.name,
            'district': address.district.name,
            'email': address.email,
            'mobile': address.mobile,
            'place': address.place,
            'province': address.province.name,
            'receiver': address.receiver,
            'tel': address.tel,
            'title': address.title,
        }

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '更新地址成功', 'address': address_dict})

    def delete(self, request, address_id):

        try:
            address = Address.objects.get(id=address_id)

            address.is_deleted = True
            address.save()
        except Exception as e:
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '删除地址失败'})

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '删除地址成功'})


class DefaultAddressView(View):
    def put(self, request, address_id):

        try:
            address = Address.objects.get(id=address_id)

            request.user.default_address = address
            request.user.save()

        except Exception as e:
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '设置默认地址失败'})

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '设置默认地址成功'})


class UpdateTitleAddressView(View):
    def put(self, request, address_id):

        json_dict = json.loads(request.body.decode())
        title = json_dict.get('title')

        try:
            address = Address.objects.get(id=address_id)

            address.title = title
            address.save()
        except Exception as e:
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '标题修改失败'})

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '标题修改成功'})
